#pragma once

// Dependencies
namespace Core {
	template<class T> class Vector3_t;
}

namespace Core {
	template<class T>
	class Point3_t {
	public: // Typedefs
		typedef T value_type;
		typedef Point3_t<T> this_type;

	public: // Constructors
		Point3_t();
		Point3_t( T x, T y, T z );

		// Convert to other Vector3-type (forbid implicit conversions)
		template<class U>
		explicit Point3_t( const Point3_t<U>& vec ) :
			x( (T)vec.x ),
			y( (T)vec.y ),
			z( (T)vec.z ) {
		}

	public: // Operators
		Point3_t<T>& operator+= ( const Vector3_t<T>& vec );
		const Point3_t<T> operator+ ( const Vector3_t<T>& vec ) const;
		Vector3_t<T> operator - ( const Point3_t<T>& vec ) const;

	public: // Methods
		const Vector3_t<T> fromOrigin() const;

	public: // Accessors
		T& operator[] ( int idx );
		const T& operator [] ( int idx ) const;

	private: // Helper members
		static T Point3_t::* const (map[3]);

	public: // Members
		T x, y, z;
	};

	// Typedefs available to the Core namespace
	typedef Point3_t<float> Point3f;
	typedef Point3_t<double> Point3;
	typedef Point3_t<int> Point3i;
}